package org.batatasframework.chart.columns;

import java.util.Iterator;
import java.util.List;

import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.batatasframework.chart.ChartCell;
import org.batatasframework.chart.data.ChartInitializer;

public abstract class AbstractChartColumn implements ChartColumn{
	
	protected final String name;
	protected int ordinal;
	
	protected AbstractChartColumn(String name){
		this.name = name;
	}

	protected int rowspan = 1;
	
	@Override
	public final int rowspan() {
		return rowspan;
	}
	
	@Override
	public int size() {
		return 1;
	}

	@Override
	public ChartColumn initialize(ChartInitializer initializer) {
		this.ordinal = initializer.allocate();
		return this;
	}

	@Override
	public final int getOrdinal() {
		return ordinal;
	}
	
	@Override
	public void resolveHead(XSSFRow[] heads, XSSFCellStyle style, int deep) {
		XSSFRow head = heads[deep];
		int rowspan = heads.length - deep - this.rowspan;
		int order = getOrdinal() + 1;//要把"序号"这一列加上去
		XSSFCell cell = head.createCell(order);
		cell.setCellStyle(style);
		cell.setCellValue(name);
		
		int firstRow = deep;
		int lastRow = deep + rowspan;
		int firstCol = order;
		int lastCol = order + size() - 1;
		if(lastRow > firstRow || lastCol > firstCol){
			XSSFSheet sheet = head.getSheet();
			sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
		}
	}
	
	@Override
	public void resolveHead(String[] heads, int deep) {
		String head = heads[deep];
		int rowspan = heads.length - deep - this.rowspan;
		head += "<th";
		if(rowspan > 0) head += " rowspan='" + (rowspan + 1) + "'";
		
		int colspan = size();
		if(colspan > 1) head += " colspan='" + colspan + "'";
		head += ">" + name + "</th>";
		heads[deep] = head;
	}
	
	protected abstract class AbstractChartCell<T> implements ChartCell{
		protected T value;
	}
	
	protected class MultipeChartCell extends AbstractChartCell<ChartCell[]>{

		private final String symbol;
		
		protected MultipeChartCell(ChartCell[] cells, String symbol){
			this.value = cells;
			this.symbol = symbol;
		}

		protected MultipeChartCell(ChartCell[] cells){
			this(cells, "-");
		}
		
		@Override
		public String toString() {
			String strValue = "";
			for(ChartCell cell : value){
				strValue += symbol + cell;
			}
			if(!symbol.isEmpty() && !strValue.isEmpty()){
				strValue = strValue.substring(symbol.length());
			}
			return strValue;
		}
		
		@Override
		public void read(Object[] row) {
			for(ChartCell cell : value){
				cell.read(row);
			}
		}
		
		@Override
		public void write(List<Object> item) {
			for(ChartCell cell : value){
				cell.write(item);
			}
		}
		
		@Override
		public void add(ChartCell augend) {
			MultipeChartCell cellAugend = (MultipeChartCell)augend;
			int len = value.length;
			for(int i = 0; i < len; i ++){
				value[i].add(cellAugend.value[i]);
			}
		}
	}
	
	@Override
	public String toString() {
		return name;
	}
}

class InternalIterator<T extends ChartColumn> implements Iterator<T>{
	private final T[] columns;
	
	private int indexOf;
	
	InternalIterator(int skipColumn, T[] columns){
		this.indexOf = skipColumn;
		this.columns = columns;
	}
	

	InternalIterator(T[] columns){
		this.columns = columns;
	}
	
	@Override
	public boolean hasNext() {
		return indexOf < columns.length;
	}

	@Override
	public T next() {
		return columns[indexOf++];
	}

	@Override
	public void remove() { }
		
}
